package io.bd;

import io.Archivo;
import io.Carpeta;
import io.Cliente;
import io.ItemBusqueda;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Mariano Zapata
 */
public class ABMRCarpeta {
    
    private Connection conexion;
    
    public static final int BUSCAR_CARPETA= 0;
    public static final int BUSCAR_ARCHIVO= 1;
    public static final int BUSCAR_CLIENTE_APELLIDO= 2;
    public static final int BUSCAR_CLIENTE_NOMBRE= 3;
    public static final int BUSCAR_CLIENTE_DNI= 4;
    
    public ABMRCarpeta(Connection conexion) {this.conexion= conexion;}
    
    public void recuperar(Carpeta carpeta, ABMRCliente auxiliarCliente, ABMRArchivo auxiliarArchivo) throws SQLException
    {
        String renglon= "SELECT id, nombre FROM Directorio WHERE padre= " + carpeta.obtenerId() + " ORDER BY nombre";
        List<Carpeta> hijos= new ArrayList<Carpeta>();
        Statement consulta= conexion.createStatement();
        ResultSet r= consulta.executeQuery(renglon);
        while (r.next())
        {
            List<Long> ruta= carpeta.obtenerCopiaRuta();
            ruta.add(r.getLong(1));
            Carpeta c= new Carpeta(ruta);
            c.setNombre(r.getString(2));
            if (this.poseeCarpetas(c) || auxiliarCliente.poseeClientes(c) || auxiliarArchivo.poseeArchivos(c))
                c.setPoseeHijos(true);
            else
                c.setPoseeHijos(false);
            hijos.add(c);
        }
        r.close();
        consulta.close();
        carpeta.setHijosCarpeta(hijos);
    }
    
    public Carpeta obtenerCarpeta(List<Long> ruta) throws SQLException
    {
        long id= ruta.get(ruta.size() - 1);
        String renglon= "SELECT * FROM Directorio WHERE id= " + id;
        Statement consulta= conexion.createStatement();
        ResultSet r= consulta.executeQuery(renglon);
        r.next();
        Carpeta retorno= new Carpeta(ruta);
        retorno.setNombre(r.getString(2));
        r.close();
        consulta.close();
        return retorno;
    }
    
    public Carpeta crear(Carpeta c, Carpeta padre) throws SQLException
    {
        String renglon= "INSERT INTO Directorio (nombre, padre) VALUES (?, ?)";
        List<Long> ruta= padre.obtenerCopiaRuta();
        PreparedStatement consulta= conexion.prepareStatement(renglon, PreparedStatement.RETURN_GENERATED_KEYS);
        consulta.setString(1, c.getNombre());
        consulta.setLong(2, padre.obtenerId());
        consulta.executeUpdate();
        ResultSet r= consulta.getGeneratedKeys();
        r.next();
        ruta.add(r.getLong(1));
        r.close();
        consulta.close();
        Carpeta ret= new Carpeta(ruta);
        ret.setNombre(c.getNombre());
        return ret;
    }
    
    public void guardar(Carpeta c) throws SQLException
    {
        String renglon= "UPDATE Directorio SET nombre= ? WHERE id= ?";
        PreparedStatement consulta= conexion.prepareStatement(renglon);
        consulta.setString(1, c.getNombre());
        consulta.setLong(2, c.obtenerId());
        consulta.executeUpdate();
        consulta.close();
    }
    
    public void eliminar(Carpeta c, ABMRCliente auxiliarCliente, ABMRArchivo auxiliarArchivo) throws SQLException
    {
        String renglon= "DELETE FROM Directorio WHERE id= " + c.obtenerId();
        Statement consulta= conexion.createStatement();
        this.recuperar(c, auxiliarCliente, auxiliarArchivo);
        List<Carpeta> hijos= c.getHijosCarpeta();
        for (Carpeta p : hijos)
            this.eliminar(p, auxiliarCliente, auxiliarArchivo);
        consulta.executeUpdate(renglon);
        consulta.close();
    }
    
    public void cortar(Carpeta c, Carpeta nuevoPadre) throws SQLException
    {
        String renglon= "UPDATE Directorio SET padre= " + nuevoPadre.obtenerId() + " WHERE id= " + c.obtenerId();
        Statement consulta= conexion.createStatement();
        consulta.executeUpdate(renglon);
        consulta.close();
    }
    
    public void copiar(Carpeta c, Carpeta nuevoPadre, ABMRCliente auxiliarCliente, ABMRArchivo auxiliarArchivo)
            throws SQLException, IOException
    {
        Carpeta nueva= this.crear(c, nuevoPadre);
        this.recuperar(c, auxiliarCliente, auxiliarArchivo);
        List<Carpeta> hijosCarpetas= c.getHijosCarpeta();
        for (Carpeta p : hijosCarpetas)
            this.copiar(p, nueva, auxiliarCliente, auxiliarArchivo);
        auxiliarCliente.recuperar(c);
        List<Cliente> hijosClientes= c.getHijosCliente();
        for (Cliente i : hijosClientes)
            auxiliarCliente.copiar(i, nueva);
        auxiliarArchivo.recuperar(c);
        List<Archivo> hijosArchivos= c.getHijosArchivo();
        for (Archivo a : hijosArchivos)
            auxiliarArchivo.copiar(a, nueva);
    }
    
    public List<ItemBusqueda> buscarCarpeta(String palabraClave) throws SQLException
    {
        String renglon= "SELECT * FROM Directorio WHERE nombre LIKE '%" + palabraClave + "%' ORDER BY nombre";
        Statement consulta= conexion.createStatement();
        List<ItemBusqueda> retorno= new ArrayList<ItemBusqueda>();
        ResultSet r= consulta.executeQuery(renglon);
        while (r.next())
        {
            List<Long> ruta= new ArrayList<Long>();
            ruta.add(r.getLong(1));
            String rutaLegible= this.rutaReversa(r.getLong(3), ruta);
            ItemBusqueda i= new ItemBusqueda(ruta);
            i.setRutaLegible(rutaLegible);
            i.setTexto(r.getString(2));
            retorno.add(i);
        }
        r.close();
        consulta.close();
        return retorno;
    }
    
    public List<ItemBusqueda> buscarArchivo(String palabraClave) throws SQLException
    {
        String renglon= "SELECT id, nombre, carpeta FROM Archivo WHERE nombre LIKE '%" + palabraClave + "%' ORDER BY nombre";
        Statement consulta= conexion.createStatement();
        List<ItemBusqueda> retorno= new ArrayList<ItemBusqueda>();
        ResultSet r= consulta.executeQuery(renglon);
        while (r.next())
        {
            List<Long> ruta= new ArrayList<Long>();
            ruta.add(r.getLong(1));
            String rutaLegible= this.rutaReversa(r.getLong(3), ruta);
            ItemBusqueda i= new ItemBusqueda(ruta);
            i.setRutaLegible(rutaLegible);
            i.setTexto(r.getString(2));
            retorno.add(i);
        }
        r.close();
        consulta.close();
        return retorno;
    }
    
    public List<ItemBusqueda> buscarClienteApellido(String palabraClave) throws SQLException
    {
        String renglon= "SELECT id, carpeta, apellido, nombre, dni FROM Cliente WHERE apellido LIKE '%" + palabraClave +
                "%' ORDER BY apellido, nombre";
        Statement consulta= conexion.createStatement();
        List<ItemBusqueda> retorno= new ArrayList<ItemBusqueda>();
        ResultSet r= consulta.executeQuery(renglon);
        while (r.next())
        {
            List<Long> ruta= new ArrayList<Long>();
            ruta.add(r.getLong(1));
            String rutaLegible= this.rutaReversa(r.getLong(2), ruta);
            ItemBusqueda i= new ItemBusqueda(ruta);
            i.setRutaLegible(rutaLegible);
            String texto= r.getString(3) + ", " + r.getString(4) + " (" + r.getInt(5) + ")";
            i.setTexto(texto);
            retorno.add(i);
        }
        r.close();
        consulta.close();
        return retorno;
    }
    
    public List<ItemBusqueda> buscarClienteNombre(String palabraClave) throws SQLException
    {
        String renglon= "SELECT id, carpeta, apellido, nombre, dni FROM Cliente WHERE nombre LIKE '%" + palabraClave +
                "%' ORDER BY nombre, apellido";
        Statement consulta= conexion.createStatement();
        List<ItemBusqueda> retorno= new ArrayList<ItemBusqueda>();
        ResultSet r= consulta.executeQuery(renglon);
        while (r.next())
        {
            List<Long> ruta= new ArrayList<Long>();
            ruta.add(r.getLong(1));
            String rutaLegible= this.rutaReversa(r.getLong(2), ruta);
            ItemBusqueda i= new ItemBusqueda(ruta);
            i.setRutaLegible(rutaLegible);
            String texto= r.getString(4) + ", " + r.getString(3) + " (" + r.getInt(5) + ")";
            i.setTexto(texto);
            retorno.add(i);
        }
        r.close();
        consulta.close();
        return retorno;
    }
    
    public List<ItemBusqueda> buscarClienteDni(String palabraClave) throws SQLException
    {
        String renglon= "SELECT id, carpeta, apellido, nombre FROM Cliente WHERE dni= " + palabraClave +
                " ORDER BY apellido, nombre";
        Statement consulta= conexion.createStatement();
        List<ItemBusqueda> retorno= new ArrayList<ItemBusqueda>();
        ResultSet r= consulta.executeQuery(renglon);
        while (r.next())
        {
            List<Long> ruta= new ArrayList<Long>();
            ruta.add(r.getLong(1));
            String rutaLegible= this.rutaReversa(r.getLong(2), ruta);
            ItemBusqueda i= new ItemBusqueda(ruta);
            i.setRutaLegible(rutaLegible);
            String texto= r.getString(3) + ", " + r.getString(4);
            i.setTexto(texto);
            retorno.add(i);
        }
        r.close();
        consulta.close();
        return retorno;
    }
    
    private String rutaReversa(long padre, List<Long> ruta) throws SQLException
    {
        Statement consulta= conexion.createStatement();
        ResultSet r;
        String rutaLegible= "";
        while (padre != -1)
        {
            String renglon= "SELECT * FROM Directorio WHERE id= " + padre;
            r= consulta.executeQuery(renglon);
            r.next();
            ruta.add(0, padre);
            if (rutaLegible.isEmpty())
                rutaLegible= r.getString(2);
            else
                rutaLegible= r.getString(2) + "/" + rutaLegible;
            padre= r.getLong(3);
            r.close();
        }
        consulta.close();
        return rutaLegible;
    }
    
    private boolean poseeCarpetas(Carpeta c) throws SQLException
    {
        String renglon= "SELECT COUNT(id) FROM Directorio WHERE padre= " + c.obtenerId();
        Statement consulta= conexion.createStatement();
        ResultSet r= consulta.executeQuery(renglon);
        r.next();
        return (r.getLong(1) > 0);
    }
}
